<?php
/*
class Am_Form_Brick_MollieBank extends Am_Form_Brick
{
    protected $labels = array(
        'Uw bank' => 'Uw bank',
    );

    public function __construct($id = null, $config = null)
    {
        $this->name = ___("Mollie Bank");
        parent::__construct($id, $config);
    }

    public function isAcceptableForForm(Am_Form_Bricked $form) {
        return $form instanceof Am_Form_Signup;
    }

    public function insertBrick(HTML_QuickForm2_Container $form)
    {
        $bank = $form->addSelect('mollie_bank')->setLabel(array('Uw bank'));
        $bank->loadOptions(Am_Paysystem_MollieIdeal::getBanks());
        if ($this->getConfig('required')){
            $bank->addRule('required', ___('Please enter %s', $this->___('Uw bank')));
        }
    }

    public function initConfigForm(Am_Form $form)
    {
        $form->addAdvCheckbox('required')->setLabel(___('Required'));
    }
}
*/

class Am_Paysystem_MollieIdeal extends Am_Paysystem_Abstract
{
    const PLUGIN_STATUS = self::STATUS_BETA;
    const PLUGIN_REVISION = '4.2.13.4d4e034';

    protected $defaultTitle = 'Mollie iDEAL';
    protected $defaultDescription = 'online betalen via uw eigen bank';
    
    protected $_canResendPostback = true;
    
    public function getSupportedCurrencies()
    {
        return array('USD', 'GBP', 'EUR', 'CAD', 'JPY');
    }

    public function _initSetupForm(Am_Form_Setup $form)
    {
        $form->addInteger('business', array('size'=>20))
            ->setLabel(array('Mollie iDEAL Partner Id', 'your partner id in mollie.nl'));
        $form->addAdvCheckbox('testing')->setLabel(array('Test Mode', 'activate Test Mode in your account at mollie.nl as well'));
    }
    
    public function isConfigured()
    {
        return $this->getConfig('business') > '';
    }
    
    public function getBanks()
    {
        require_once(dirname(__FILE__).'/Mollie/Ideal.php');
        $banksArray = array();
        $testmode = ($this->getConfig('testing') == "1" ? true : false);
        $ideal = new Mollie_Ideal($this->getConfig('business'));
        $banksArray = $ideal->getBanks($testmode);
        return $banksArray;
    }

    public function _process(Invoice $invoice, Am_Request $request, Am_Paysystem_Result $result)
    {
        
        $partnerId = $this->getConfig('business');
        $checksum = md5($invoice->getLineDescription() . $invoice->first_total. $invoice->public_id . $invoice->user_id . $partnerId);

        $banksSelect = "<select name=\"mollie_ideal_bank\">\r\n";
        foreach ($this->getBanks() as $key => $value){
                $banksSelect.="<option value=\"" . $key . "\">" . $value . "</option>\r\n";
        }
        $banksSelect .= "</select>\r\n";
        
        $public = "/application/default/plugins/payment/mollie-ideal/public";

        $html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n";
        $html.= "<html>\r\n";
        $html.= "<head>\r\n";
        $html.= "<title>iDEAL betaling</title>\r\n";
        $html.= "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $this->getRootUrl() . $public . "/style.css\">\r\n";
        $html.= "<script type=\"text/javascript\" language=\"Javascript\">";
        $html.= "  function bodyOnLoad() {";
        $html.= "    if (top != self) {";
        $html.= "      parent.scrollTo(0,0); "; 
        $html.= "      scrollTo(0,0); ";
        $html.= "    }";
        $html.= "  }";
        $html.= "</script>";
        $html.= "</head>\r\n";
        $html.= "<body onload=\"bodyOnLoad()\">\r\n";
        $html.= "<center>\r\n";
        $html.= "<br/><table id=\"outer\"><tr><td>\r\n";
        $html.= "<img src=\"" . $this->getRootUrl() . $public . "/ideal.gif\" align=\"right\"><h2>iDEAL betaling</h2>\r\n";
        $html.= "<b>Selecteer uw bank</b><br/>Selecteer uw bank en klik op 'Verder' om door te<br/>gaan naar het iDEAL betaalscherm van uw bank.<br/><br/>\r\n";
        $html.= "<form method=\"post\" action=\"" . $this->getPluginUrl('pay') . "\" target=\"_top\">\r\n";
        $html.= "<table id=\"inner\">\r\n";
        $html.= "<tr><td><b>Omschrijving</b></td><td width=\"300px\">" . $invoice->getLineDescription() . "</td></tr>\r\n";
        $html.= "<tr><td><b>Bedrag</b></td><td>" . number_format($invoice->first_total, 2, ',', '') . "</td></tr>\r\n";
        $html.= "<tr><td><b>Uw bank</b></td><td>" . $banksSelect . "</td></tr>\r\n";
        $html.= "</table>\r\n";
        $html.= "<input type=\"hidden\" name=\"description\" value=\"" . $invoice->getLineDescription() . "\">\r\n";
        $html.= "<input type=\"hidden\" name=\"price\" value=\"" . $invoice->first_total . "\">\r\n";
        $html.= "<input type=\"hidden\" name=\"payment_id\" value=\"" . $invoice->public_id . "\">\r\n";
        $html.= "<input type=\"hidden\" name=\"member_id\" value=\"" . $invoice->user_id . "\">\r\n";

        $html.= "<input type=\"hidden\" name=\"checksum\" value=\"" . $checksum . "\">\r\n";

        $html.= "<center>\r\n";
        $html.= "<br/><br/><input type=\"submit\" value=\"Verder\" />\r\n";
        $html.= "</center>\r\n";
        $html.= "</form>\r\n";
        $html.= "</td></tr></table>\r\n";
        $html.= "<div id=\"info\">\r\n";
        $html.= "<a href=\"#\" onClick=\"JavaScript:window.open('http://www.mollie.nl/docs/ideal.php', '_blank','width=400,height=500');return false;\">Wat is iDEAL en wat is Mollie?</a>\r\n";
        $html.= "</div>\r\n";
        $html.= "</center>\r\n";
        $html.= "</body>\r\n";
        echo $html;
        exit;

    }
    
    public function getRecurringType()
    {
        return self::REPORTS_NOT_RECURRING;
    }

    public function getReadme()
    {
return <<<CUT
            Mollie iDeal payment plugin configuration

This plugin allows you to use Mollie iDEAL for payment. You have to
register for an account at Mollie.nl to use this plugin.
CUT;
    }

    public function createTransaction(Am_Request $request, Zend_Controller_Response_Http $response, array $invokeArgs)
    {
        return new Am_Paysystem_Transaction_MollieIdeal($this, $request, $response, $invokeArgs);
    }

}

class Am_Paysystem_Transaction_MollieIdeal extends Am_Paysystem_Transaction_Incoming
{
    protected $_case = 'ipn'; //pay, status
    protected $_params = array();
        
    function __construct(Am_Paysystem_Abstract $plugin, Am_Request $request, Zend_Controller_Response_Http $response, $invokeArgs)
    {
        parent::__construct($plugin, $request, $response, $invokeArgs);

        $PathInfo = $request->getPathInfo();
        $this->_case = substr($PathInfo, strrpos($PathInfo, '/') + 1);
        $this->_params = $this->request->isPost() ? $this->request->getPost() : $this->request->getQuery();

        $invoice = $this->getInvoice();
        //Am_Di::getInstance()->invoiceTable->findFirstByPublicId($payment_id);
        $receipt_id = Am_Di::getInstance()->invoicePaymentTable->getLastReceiptId($invoice->invoice_id);
        if ($receipt_id)
                $this->_params['transaction_id'] = $receipt_id;
        
    }

    public function findInvoiceId()
    {
        return (isset($this->_params['payment_id'])) ? $this->_params['payment_id'] : '';
    }
    public function getUniqId()
    {
        return (isset($this->_params['transaction_id'])) ? $this->_params['transaction_id'] : '';
    }
    public function validateSource()
    {
        return true;
    }
    public function validateStatus()
    {
        return true;
    }
    public function validateTerms()
    {   
        return true;
    }
    public function getAmount()
    {
        return (isset($this->_params['price'])) ? $this->_params['price'] : '';
    }
    public function processValidated()
    {
        require_once(dirname(__FILE__).'/Mollie/Ideal.php');

        $partnerId = $this->getPlugin()->getConfig('business');
        $ideal = new Mollie_Ideal($partnerId);
        $testmode = ($this->getPlugin()->getConfig('testing') == "1" ? true : false);
        $public = "/application/default/plugins/payment/mollie-ideal/public";
        $invoice = $this->getInvoice();
        $mollieTransactionId = $this->getUniqId();
        
        if ($this->_case == 'pay') {

            $mollieBankId   = $this->_params['mollie_ideal_bank'];
            $description    = $this->_params['description'];
            $price          = $this->_params['price'];
            $payment_id     = $this->_params['payment_id'];
            $member_id      = $this->_params['member_id'];

            $checksum = md5($description . $price . $payment_id . $member_id . $partnerId);
            if ($this->_params['checksum'] != $checksum)
                    throw new Am_Exception_Paysystem_TransactionInvalid('Mollie Ideal: Checksum error');

            if ($ideal->checkBank($mollieBankId, $testmode)) {

                    // Create the payment, true on succes, false otherwise
                    // $mollieBankId = the id of the bank the user chose
                    // $description  = the description that the user will see on his check
                    // $amount = the total amount of money that the user has to pay
                    // $siteReportUrl = the url which will be called from the Mollie server when the payment is complete.
                    //                  Mollie will add ?transaction_id=<transactionId> to this url!
                    // $siteReturnUrl = the url where Mollie returns the user to when the payment is complete.
                    //                  Mollie will add ?transaction_id=<transactionId> to this url!

                    
                    $amount = sprintf('%d', $price * 100);
                    $siteReportUrl = $this->getPlugin()->getPluginUrl('ipn') . "?payment_id=" . $payment_id;
                    $siteReturnUrl = $this->getPlugin()->getPluginUrl('status') . "?payment_id=" . $payment_id;

                    // for testing only
                    $siteReportUrl = str_replace('localhost', 'yourdomain.com', $siteReportUrl);
                    $siteReturnUrl = str_replace('localhost', 'yourdomain.com', $siteReturnUrl);

                    if ($ideal->createPayment($mollieBankId, $description, $amount, $siteReportUrl, $siteReturnUrl)) {
                        // Get the url of the chosen bank to redirect the user to,
                        // to complete the payment
                        //$a = new Am_Paysystem_Action_Redirect($ideal->getBankUrl());
                        //$result->setAction($a);
                        header('Location: ' . $ideal->getBankUrl());
                        exit;
                    } else {
                        // show message that the payment could not be created
                        // the function $ideal->getStatus() returns the status
                        // message that Mollie returns
                        throw new Am_Exception_Paysystem_TransactionInvalid('Mollie Ideal error: Status = [' . $ideal->getStatus() . ']');
                    }

            } else {
                throw new Am_Exception_Paysystem_TransactionInvalid('Mollie Ideal error: CheckBank Failed');
            }

        } elseif ($this->_case == 'status') {

            if ($invoice->status > 0){
                    $status = "Wij hebben uw betaling ontvangen.";
            } else {
                    $status = "Wij hebben uw betaling nog niet ontvangen.<br />Uw iDEAL betaling is wellicht nog onderweg.";
                    $status.= "<br />Wacht enkele minuten en ververs dan deze pagina.<br />Bij problemen kunt u contact opnemen met " . Am_Di::getInstance()->config->get('admin_email') . ".";
                    $status.= "<br /><b>Noteer uw betaalcode.</b>";
            }

            $html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n";
            $html.= "<html>\r\n";
            $html.= "<head>\r\n";
            $html.= "<title>iDEAL betaling</title>\r\n";
            $html.= "<link rel=\"stylesheet\" type=\"text/css\" href=\"" . $this->getPlugin()->getRootUrl() . $public . "/style.css\">\r\n";
            $html.= "</head>\r\n";
            $html.= "<body>\r\n";
            $html.= "<center>\r\n";
            $html.= "<br/><table id=\"outer\"><tr><td>\r\n";
            $html.= "<img src=\"" . $this->getPlugin()->getRootUrl() . $public . "/ideal.gif\" align=\"right\"><h2>iDEAL betaling</h2>\r\n";
            $html.= "<b>Betaalstatus</b><br/><br/>\r\n";
            $html.= "<table id=\"inner\">\r\n";
            $html.= "<tr><td><b>Betaalstatus</b></td><td width=\"300px\">" . $status . "</td></tr>\r\n";
            $html.= "<tr><td><b>Betaalcode</b></td><td>" . $invoice->public_id . "/" . $mollieTransactionId . "</td></tr>\r\n";
            $html.= "</table>\r\n";
            $html.= "<form method=\"post\" action=\"" . $this->getPlugin()->getRootUrl() ."/member\" target=\"_top\">\r\n";
            $html.= "<center><br/><br/><input type=\"submit\" value=\"Verder\" /></center>\r\n";
            $html.= "</form>\r\n";
            $html.= "</td></tr></table>\r\n";
            $html.= "</center>\r\n";
            $html.= "</body>\r\n";
            print $html;
            exit;
            
        } elseif ($this->_case == 'ipn') {
            
            // Chech if the given transaction Id is valid
            if ($ideal->checkPayment($mollieTransactionId) == true) {
                // process payment
                $this->invoice->addPayment($this);
            } else {
                // Payment failed
                throw new Am_Exception_Paysystem_TransactionInvalid('Mollie Ideal error: Status = [' . $ideal->getStatus() . ']');
            }
            
        } else {
            throw new Am_Exception_Paysystem_TransactionInvalid('Mollie Ideal error: Unknowk case [' . $this->_case . ']');
        }
        
    }
}
